package com.edfeff.bio;


import com.edfeff.bio.http.HttpHandler;
import com.edfeff.bio.http.IAdapter;
import com.edfeff.bio.http.ServerConfig;
import com.edfeff.bio.http.StsException;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleHttpServer {


    /**
     * 服务器配置
     */
    private final ServerConfig config;

    private IAdapter adapter;

    public IAdapter getAdapter() {
        return adapter;
    }

    private volatile boolean running = false;
    private ServerSocket serverSocket;

    public SimpleHttpServer(ServerConfig config) {
        this.config = config;
    }

    public void start() {
        // STS 启动！
        try {
            init();
            startInternal();
        } catch (Exception e) {
            this.stop();
            throw new StsException(e.getMessage());
        }
        hold();
    }

    private void hold() {
        //防止进程退出
    }

    private void init() throws IOException {
        //todo 配置serverSocket
        serverSocket = new ServerSocket();

        //创建 Adapter
        try {
            Class<? extends IAdapter> adapterClazz = config.getAdapterClass();
            Constructor<? extends IAdapter> declaredConstructor = adapterClazz.getDeclaredConstructor();
            this.adapter = declaredConstructor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //启动状态
        this.running = true;
    }

    private void startInternal() throws IOException {
        serverSocket.bind(new InetSocketAddress(config.getPort()));
        while (running) {
            Socket clientSocket = serverSocket.accept();
            HttpHandler handlerTask = new HttpHandler(this, clientSocket);

            //传统线程模型
            new Thread(handlerTask).start();

            //虚拟线程模型
//            Thread.startVirtualThread(handlerTask);
        }
    }

    public void stop() {
        this.running = false;
        //todo 关闭线程池
        //todo 关闭服务器
        //todo 释放资源
    }

}